-
Notifications
You must be signed in to change notification settings - Fork 45
fix(safe-parse): add safe JSON parse utility and apply to AI services… #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix(safe-parse): add safe JSON parse utility and apply to AI services… #49
Conversation
… and dataset; add tests
Summary of ChangesHello @morningstarxcdcode, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request lays the groundwork for the LocalMind backend, focusing on establishing a robust and scalable architecture. It integrates multiple AI models, sets up a flexible prompt templating system, and implements essential user authentication and AI agent configuration features. The changes also include utilities for safe JSON parsing and automated development environment setup, ensuring a solid foundation for future development. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a substantial amount of new functionality, including the initial project structure, AI service integrations for Google, Groq, and Ollama, and a new safeParse utility. The setup is comprehensive, but there are several critical issues that need to be addressed. These include non-existent package versions in package.json that will break the build, required environment variables that seem to be for testing purposes and will cause the app to crash, and several logical bugs in the AI model configuration and user services. I've left detailed comments on these issues, along with suggestions for fixes. Great start, and looking forward to seeing these issues resolved!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request establishes the foundational backend infrastructure for LocalMind, a platform enabling users to interact with AI models locally or via cloud APIs. The changes introduce environment configuration, user authentication, AI model integrations (Google Gemini, Groq, Ollama), a safe JSON parsing utility, dataset processing capabilities, and project tooling for development and testing.
Key Changes:
- Environment validation schema with support for server, database, JWT, Redis, and AI API configurations
- User authentication system with JWT tokens, password hashing (Argon2), and API key generation
- AI model service integrations with prompt templating and safe JSON response parsing
- Safe JSON parsing utility to handle AI response parsing with fallback support
Reviewed changes
Copilot reviewed 57 out of 65 changed files in this pull request and generated 39 comments.
Show a summary per file
| File | Description |
|---|---|
types/express.d.ts |
Extends Express Request to include optional user property for authentication |
tsconfig.json |
TypeScript configuration with strict mode and ES2022 target |
src/validator/env.ts |
Environment variable validation schema using Zod |
src/utils/safeJson.util.ts |
Safe JSON parser utility with error handling and fallback |
src/utils/__test__/safeJson.util.test.ts |
Unit tests for safe JSON parsing utility |
src/utils/SendResponse.utils.ts |
Standardized success/error response utility |
src/server.ts |
Main server initialization with MongoDB connection |
src/routes/app.ts |
Central route aggregation and middleware setup |
src/config/mongoose.connection.ts |
MongoDB connection handler with retry logic |
src/constant/env.constant.ts |
Environment constant exports with validation |
src/constant/Status.constant.ts |
HTTP status code enum definitions |
src/api/v1/user/* |
Complete user module (model, service, controller, routes, middleware, tests) |
src/api/v1/AiModelConfig/* |
AI model configuration management system |
src/api/v1/DataSet/v1/* |
Dataset processing with CSV loading and AI extraction |
src/api/v1/Ai-model/Google/* |
Google Gemini AI integration |
src/api/v1/Ai-model/Groq/* |
Groq AI integration |
src/api/v1/Ai-model/Ollama/* |
Ollama local AI integration with embeddings |
src/Template/v1/* |
AI prompt template system with dynamic variable substitution |
src/data/Sample.csv |
Sample dataset for testing data processing |
src/doc/*.json |
Postman API collection for testing endpoints |
package.json |
Project dependencies and scripts |
jest.config.ts |
Jest testing configuration |
.prettierrc, .prettierignore |
Code formatting configuration |
.gitignore |
Git ignore patterns |
.env.example |
Environment variable template |
setup-cloudflare.sh |
Cloudflare tunnel setup script |
a.md |
Documentation for training data and tunneling |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import { ChartWithGroq_type } from './Groq.type' | ||
| import { env } from '../../../../constant/env.constant' | ||
| import AiTemplate from '../../../../Template/v1/Ai.template' | ||
| import { safeParse } from '../../../../utils/safeJson.util' | ||
|
|
||
| class GroqService { | ||
| public async ChartWithGroq(data: ChartWithGroq_type): Promise<any> { |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The imported type 'ChartWithGroq_type' should be 'ChatWithGroq_type' to correctly represent a chat interaction.
| import { ChartWithGroq_type } from './Groq.type' | |
| import { env } from '../../../../constant/env.constant' | |
| import AiTemplate from '../../../../Template/v1/Ai.template' | |
| import { safeParse } from '../../../../utils/safeJson.util' | |
| class GroqService { | |
| public async ChartWithGroq(data: ChartWithGroq_type): Promise<any> { | |
| import { ChatWithGroq_type } from './Groq.type' | |
| import { env } from '../../../../constant/env.constant' | |
| import AiTemplate from '../../../../Template/v1/Ai.template' | |
| import { safeParse } from '../../../../utils/safeJson.util' | |
| class GroqService { | |
| public async ChartWithGroq(data: ChatWithGroq_type): Promise<any> { |
| if (!existingConfig) { | ||
| CreateConfig = await AiModelConfigService.setupAiModelConfig({ | ||
| userId: String(FindUserByToken._id), | ||
| agents: [{} as IAgent], |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setupAiModelConfig method creates an initial config with an empty agent object {} as IAgent, which will fail validation. The agent schema requires provider, type, and model fields. This should either not create an initial empty agent or should handle the initial config creation differently.
| agents: [{} as IAgent], | |
| agents: [] as IAgent[], |
|
|
||
| SendResponse.success(res, 'AI response generated successfully', Ai_Response, 200) | ||
| } catch (err: any) { | ||
| console.log('err', err) |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The console.log statement for error 'err' should be removed or replaced with proper error logging. Production code should use a logging framework instead of console.log for errors.
| if (typeof result === 'string') { | ||
| return safeParse(result, result) |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The safeParse usage here doesn't make sense. When the response is already a string, calling safeParse with the string as both input and fallback will either parse it as JSON or return the original string. This means non-JSON string responses will be passed through unchanged, which may not be the intended behavior. Consider clarifying the expected response format.
| @@ -0,0 +1,11 @@ | |||
| To Train al model we use Csv , Excel , pdf | |||
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spelling error in 'al model' should be 'AI model' (capital 'AI').
| To Train al model we use Csv , Excel , pdf | |
| To Train AI model we use Csv , Excel , pdf |
| return Promise.resolve(crypto.randomBytes(32).toString('hex')) | ||
| } | ||
|
|
||
| const hasedRawKey = (rawKey: string): Promise<string> => { |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function name 'hasedRawKey' contains a spelling error. It should be 'hashedRawKey' (with two 'h's). The function performs hashing, so the correct past tense of 'hash' is 'hashed'.
| }) | ||
| } | ||
|
|
||
| export default mongooseConection |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exported default 'mongooseConection' has a spelling error. It should be 'mongooseConnection' to match the corrected function name.
| try { | ||
| const { model, apiKey, message } = req.body | ||
|
|
||
| const chat = await GroqService.ChartWithGroq({ model, apiKey, message }) |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The service method call 'ChartWithGroq' should be 'ChatWithGroq' to correctly represent a chat interaction.
| const chat = await GroqService.ChartWithGroq({ model, apiKey, message }) | |
| const chat = await GroqService.ChatWithGroq({ model, apiKey, message }) |
| async removeAgent(userId: string, _agentId: string): Promise<IAiModelConfig | null> { | ||
| const config = (await AiModelConfig.findOne({ userId }).exec()) as any | ||
|
|
||
| if (!config) { | ||
| throw new Error('AI Model Config not found for the user.') | ||
| } | ||
|
|
||
| return await config.save() |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removeAgent method doesn't actually remove the agent. After finding the config, it immediately calls save() without removing any agent from the agents array. The implementation is incomplete and should include logic to filter out the agent with the given _agentId before saving.
|
|
||
| const Prepare_dataSet = await DataSetService.Prepare_DataSet(documents) | ||
|
|
||
| const parsed = typeof Prepare_dataSet === 'string' ? safeParse(Prepare_dataSet, Prepare_dataSet) : Prepare_dataSet |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The safeParse usage is redundant. When Prepare_dataSet is already a string, parsing it with itself as the fallback means if parsing fails, it returns the unparsed string. When it's not a string, it's returned as-is. This logic should be clearer about what format is expected and handle parsing failures appropriately.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This pull request sets up the initial backend project structure for LocalMind, including environment configuration, code formatting, and the foundation for AI model integrations (Google Gemini and Groq). It introduces configuration files, scripts, and the first implementation of AI-related API endpoints and services.
Project Setup & Configuration
.env.examplewith all necessary environment variables for server, database, JWT, Redis, uploads, and API keys.package.jsonwith project metadata, scripts for development, testing, formatting, and dependencies for Express, LangChain, AI models, and utilities.AI Model Integration: Google Gemini
GoogleService,GoogleController, andGoogleRoutesto provide an API endpoint for interacting with the Gemini AI model, using a customizable prompt template and safe JSON parsing. [1] [2] [3]GeminiUtilsclass to configure and invoke the Google Gemini model via LangChain, supporting dynamic prompt formatting and response parsing.AI Model Integration: Groq
GroqService,GroqController, andGroqRouterfor Groq model chat endpoint, with error handling and configurable model/apiKey support. [1] [2] [3]Prompt Template System
AiTemplateclass and prompt text file to standardize AI assistant behavior and response format, enforcing strict JSON output and privacy-respecting instructions. [1] [2]Developer Utilities
setup-cloudflare.shto automate Cloudflared tunnel setup for local development, including installation and authentication steps.\n\nFixes 🐛 Unhandled JSON parsing in AI services and dataset processing #42 - Adds 'safeParse' utility and applies it across Google, Groq, Ollama, and DataSet services to avoid unhandled JSON parse errors.